﻿using DataModels.Dto;
using DataModels.Dto.Community;
using DataModels.Entities.AuthCore;
using DataModels.Entities.Base;
using DataModels.Entities.Community;
using Dm.util;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace Services.Community
{
    /// <summary>
    /// 物业公告接口
    /// </summary>
    public class PropertyAnnouncementService(SqlSugarClient db) : BaseService(db)
    {
        /// <summary>
        /// 获取物业公告列表
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public ResponseModel GetPropertyAnnouncement(GetPropertyAnnouncementiInfo info, Guid? PropertyAnnouncementUUID = null, string? search = null)
        {
            try
            {
                int total = 0;
                var res = db.Queryable<PropertyAnnouncement>()
                    .Where(pa => pa.Status == DataModels.Enums.GeneralEnum.Status.Enable) 
                    .OrderBy(pa => pa.CreateTime, OrderByType.Desc)
                    .WhereIF(PropertyAnnouncementUUID.HasValue, pa => pa.UUID == PropertyAnnouncementUUID)
                    //搜索
                    .WhereIF(!string.IsNullOrEmpty(search), pa => pa.Title.Contains(search))
                    .WhereIF(info.ProjectUUID.HasValue, pa => pa.ProjectUUID.ToString().Contains(info.ProjectUUID.Value.ToString())) //控制只获取本小区公告
                    .Select(pa => new GetPropertyAnnouncementResponse
                    {
                        UUID = pa.UUID,
                        ProjectUUID = pa.ProjectUUID,
                        Title = pa.Title,
                        Content = pa.Content,
                        Image = pa.Image,
                        PageView = pa.PageView,
                        IsTop = pa.IsTop
                    })
                    .ToPageList(info.PageNumber, info.PageSize, ref total);

                List<Guid> ids = [.. res.Select(res => res.UUID)];

                /// 获取当前用户的已读记录
                List<Guid> pars = db.Queryable<PropertyAnnouncementReads>()
                    .Where(par => par.CreateUserUUID == UserUUID)
                    .Where(par => ids.Contains(par.PropertyAnnouncementUUID))
                    .Select(par => par.PropertyAnnouncementUUID)
                    .ToList();

                /// 获取当前用户的点赞记录
                List<Guid> pals = db.Queryable<PropertyAnnouncementLikes>()
                    .Where(pal => pal.CreateUserUUID == UserUUID)
                    .Where(pal => ids.Contains(pal.PropertyAnnouncementUUID))
                    .Select(pal => pal.PropertyAnnouncementUUID)
                    .ToList();

                /// 获取当前用户订阅记录
                bool pas = db.Queryable<PropertyAnnouncementSubscriptions>()
                    .Where(pas => pas.CreateUserUUID == UserUUID)
                    .Any();

                foreach (var item in res)
                {
                    item.IsRead = pars.Contains(item.UUID) ? DataModels.Enums.GeneralEnum.Status.Enable : DataModels.Enums.GeneralEnum.Status.Disable;
                    item.IsLike = pals.Contains(item.UUID) ? DataModels.Enums.GeneralEnum.Status.Enable : DataModels.Enums.GeneralEnum.Status.Disable;
                    item.IsSubscribe = pas ? DataModels.Enums.GeneralEnum.Status.Enable : DataModels.Enums.GeneralEnum.Status.Disable;
                    item.LikesCount = db.Queryable<PropertyAnnouncementLikes>()
                        .Where(pal => pal.PropertyAnnouncementUUID == item.UUID)
                        .Count();
                    item.CommentCount = db.Queryable<PropertyAnnouncementComments>()
                        .Where(pac => pac.PropertyAnnouncementUUID == item.UUID)
                        .Count();
                }
                db.BeginTran();
                if (PropertyAnnouncementUUID.HasValue)
                {
                    // 记录已读状态
                    bool padexist = db.Queryable<PropertyAnnouncementReads>()
                        .Where(pad => pad.PropertyAnnouncementUUID == PropertyAnnouncementUUID)
                        .Where(pad => pad.CreateUserUUID == UserUUID)
                        .Any();
                    if (!padexist)
                    {
                        PropertyAnnouncementReads padmodel = new()
                        {
                            PropertyAnnouncementUUID = PropertyAnnouncementUUID.Value,
                            CreateUserUUID = UserUUID,
                            CreateTime = DateTime.Now
                        };
                        db.Insertable(padmodel).ExecuteCommand();
                    }
                    // 记录浏览量
                    db.Updateable<PropertyAnnouncement>()
                        .SetColumns(pa => new PropertyAnnouncement { PageView = pa.PageView + 1 })
                        .Where(pa => pa.UUID == PropertyAnnouncementUUID)
                        .ExecuteCommand();
                }
                db.CommitTran();
                return Success(res);
            }
            catch(Exception ex) 
            {
                db.RollbackTran();
                return Error($"获取物业公告列表失败{ex.Message}");
            }
        }

        public PropertyAnnouncement Checkexist(Guid PropertyAnnouncementUUID)
        {
            return db.Queryable<PropertyAnnouncement>()
                .Where(pa => pa.UUID == PropertyAnnouncementUUID)
                .Where(pa => pa.Status == DataModels.Enums.GeneralEnum.Status.Enable)
                .First();
        }

        /// <summary>
        /// 订阅物业公告
        /// </summary>
        /// <returns></returns>
        public ResponseModel SubscribeToPropertyAnnouncement()
        {
            bool pasexist = db.Queryable<PropertyAnnouncementSubscriptions>().Where(pas => pas.CreateUserUUID == UserUUID).Any();
            if (pasexist)
            {
                return Success("已订阅");
            }
            PropertyAnnouncementSubscriptions pasmodel = new() { CreateUserUUID = UserUUID };
            db.Insertable(pasmodel).ExecuteCommand();
            return Success("已订阅");
        }

        /// <summary>
        /// 取消订阅物业公告
        /// </summary>
        /// <returns></returns>
        public ResponseModel UnsubscribePropertyAnnouncement()
        {
            PropertyAnnouncementSubscriptions pasmodel = db.Queryable<PropertyAnnouncementSubscriptions>().Where(pas => pas.CreateUserUUID == UserUUID).First();
            if (pasmodel == null)
            {
                return Success("已取消订阅");
            }
            db.Deleteable(pasmodel).ExecuteCommand();
            return Success("已取消订阅");
        }

        /// <summary>
        /// 点赞物业公告
        /// </summary>
        /// <param name="PropertyAnnouncementUUID"></param>
        /// <returns></returns>
        public ResponseModel LikePropertyAnnouncement(Guid PropertyAnnouncementUUID)
        {

            PropertyAnnouncement pamodel = Checkexist(PropertyAnnouncementUUID);
            if (pamodel == null)
            {
                return Error("物业公告不存在或已被删除");
            }

            PropertyAnnouncementLikes palmodel = db.Queryable<PropertyAnnouncementLikes>()
                .Where(pal => pal.PropertyAnnouncementUUID == PropertyAnnouncementUUID)
                .Where(pal => pal.CreateUserUUID == UserUUID)
                .First();
            if (palmodel != null)
            {
                return Success("已点赞");
            }
            palmodel = new PropertyAnnouncementLikes
            {
                PropertyAnnouncementUUID = PropertyAnnouncementUUID,
                CreateUserUUID = UserUUID
            };
            db.Insertable(palmodel).ExecuteCommand();
            return Success("已点赞");
        }

        /// <summary>
        /// 取消点赞物业公告
        /// </summary>
        /// <param name="PropertyAnnouncementUUID"></param>
        /// <returns></returns>
        public ResponseModel UnLikePropertyAnnouncement(Guid PropertyAnnouncementUUID)
        {
            PropertyAnnouncement pamodel = Checkexist(PropertyAnnouncementUUID);
            if (pamodel == null)
            {
                return Error("物业公告不存在或已被删除");
            }
            PropertyAnnouncementLikes palmodel = db.Queryable<PropertyAnnouncementLikes>()
                .Where(pal => pal.PropertyAnnouncementUUID == PropertyAnnouncementUUID)
                .Where(pal => pal.CreateUserUUID == UserUUID)
                .First();
            if (palmodel == null)
            {
                return Success("已取消点赞");
            }
            db.Deleteable(palmodel).ExecuteCommand();
            return Success("已取消点赞");
        }

        /// <summary>
        /// 创建物业公告评论
        /// </summary>
        /// <returns></returns>
        public ResponseModel CreatePropertyAnnouncementComments(CreatePropertyAnnouncementCommentsInfo info)
        {
            if (info == null)
                return Error("缺失参数");

            try
            {
                PropertyAnnouncement pamodel = Checkexist(info.PropertyAnnouncementUUID);
                if (pamodel == null)
                    return Error("物业公告不存在或已被删除");

                if (info.ParentCommentUUID.HasValue)
                {
                    bool pac = db.Queryable<PropertyAnnouncementComments>()
                        .Where(pac => pac.UUID == info.ParentCommentUUID)
                        .Where(pac => pac.PropertyAnnouncementUUID == info.PropertyAnnouncementUUID)
                        .Where(pac => pac.Status == DataModels.Enums.GeneralEnum.CommentStatus.Approved)
                        .Any();
                    if (!pac)
                        return Error("父级评论不存在或尚未审核通过");
                }
                PropertyAnnouncementComments pacmodel = new()
                {
                    UUID = Guid.NewGuid(),
                    PropertyAnnouncementUUID = info.PropertyAnnouncementUUID,
                    ParentCommentUUID = info.ParentCommentUUID,
                    Content = info.Content,
                    Status = DataModels.Enums.GeneralEnum.CommentStatus.Draft,
                    CreateUserUUID = UserUUID,
                    CreateUserName = UserName
                };
                db.Insertable(pacmodel).ExecuteCommand();
                // 写入图片
                info.Urls.ForEach(url => db.Insertable(new Attachment { BusinessId = pacmodel.UUID, Url = url, CreatedBy = UserUUID }).ExecuteCommand());
                return Success();
            }
            catch (Exception ex)
            { 
                return Error($"创建物业公告评论失败 {ex.Message}");
            }
        }

        /// <summary>
        /// 获取物业公告评论列表（包含主评论和子评论）
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public ResponseModel GetPropertyAnnouncementComments(PropertyAnnouncementRequest info)
        {
            int total = 0;

            if (info == null)
                return Error("缺失参数");

            PropertyAnnouncement pamodel = Checkexist(info.PropertyAnnouncementUUID);
            if (pamodel == null)
                return Error("物业公告不存在或已被删除");
            try
            {
                // 第一步：查询主评论
                var mainComments = db.Queryable<PropertyAnnouncementComments, User>((pac, u) => new object[]
                {
                JoinType.Left,pac.CreateUserUUID == u.UUID
                })
                .Where(pac => pac.PropertyAnnouncementUUID == info.PropertyAnnouncementUUID)
                .Where(pac => pac.Status == DataModels.Enums.GeneralEnum.CommentStatus.Approved)
                .Where(pac => pac.ParentCommentUUID == null)
                .OrderBy(pac => pac.CreateTime, OrderByType.Desc)
                .Select((pac, u) => new GetPropertyAnnouncementComments
                {
                    PropertyAnnouncementCommentsUUID = pac.UUID,
                    Content = pac.Content,
                    CreateUserUUID = pac.CreateUserUUID,
                    CreateUserName = pac.CreateUserName,
                    CreateTime = pac.CreateTime,
                    Images = new List<string>(),
                    Children = new List<GetPropertyAnnouncementComments>() // 初始化空列表
                })
                .ToPageList(info.PageNumber, info.PageSize, ref total);

                // 第二步：为每个主评论查询子评论
                foreach (var comment in mainComments)
                {
                    comment.Children = GetChildComments(comment.PropertyAnnouncementCommentsUUID);
                    comment.Images = db.Queryable<Attachment>().Where(att => att.BusinessId == comment.PropertyAnnouncementCommentsUUID).Select(att => att.Url).ToList();
                }

                return Success(new
                {
                    Total = total,
                    Comments = mainComments
                });
            }catch (Exception ex)
            {
                return Error($"获取物业公告评论列表（包含主评论和子评论）失败 {ex.Message}");
            }
        }

        // 递归获取子评论
        private List<GetPropertyAnnouncementComments> GetChildComments(Guid parentCommentUUID)
        {
            var childComments = db.Queryable<PropertyAnnouncementComments, User>((pac, u) => new object[]
            {
                JoinType.Left,pac.CreateUserUUID == u.UUID
            })
            .Where(pac => pac.ParentCommentUUID == parentCommentUUID)
            .Where(pac => pac.Status == DataModels.Enums.GeneralEnum.CommentStatus.Approved)
            .OrderBy(pac => pac.CreateTime, OrderByType.Asc)
            .Select((pac, u) => new GetPropertyAnnouncementComments
            {
                PropertyAnnouncementCommentsUUID = pac.UUID,
                Content = pac.Content,
                CreateUserUUID = pac.CreateUserUUID,
                CreateUserName = pac.CreateUserName,
                CreateTime = pac.CreateTime,
                Images = new List<string>(),
                Children = new List<GetPropertyAnnouncementComments>() // 初始化空列表
            })
            .ToList();

            // 递归查询子评论的子评论
            foreach (var childComment in childComments)
            {
                childComment.Children = GetChildComments(childComment.PropertyAnnouncementCommentsUUID);
                childComment.Images = db.Queryable<Attachment>().Where(att => att.BusinessId == childComment.PropertyAnnouncementCommentsUUID).Select(att => att.Url).ToList();
            }
            return childComments.Cast<GetPropertyAnnouncementComments>().ToList();
        }


        /// <summary>
        /// 删除物业公告评论，只能删除自己的，如遇有子级评论一并删除。 add by tianjh 20250806
        /// </summary>
        /// <param name="UUID"></param>
        /// <returns></returns> 
        public ResponseModel DelPropertyAnnouncementComments(Guid UUID)
        {    
            try
            {
                var main = db.Queryable<PropertyAnnouncementComments>().First(x => x.UUID == UUID);
                if (main == null)
                    return Error("资源不存在");

                if(main.CreateUserUUID != UserUUID)
                    return Error("只允许删除自己的评论");

                var sub = db.Queryable<PropertyAnnouncementComments>()
                .Where(x => x.ParentCommentUUID == main.UUID)
                .ToList();

                db.Ado.BeginTran(); //开启事物
                db.Deleteable(main).ExecuteCommand();

                if (sub != null)
                    db.Deleteable(sub).ExecuteCommand();

                db.Ado.CommitTran(); //提交事物
                return Success("物业联系方式删除成功");
            }
            catch (Exception ex)
            {
                db.Ado.RollbackTran(); //回滚事物
                return Error($"物业公告评论删除失败 {ex.Message}");
            }
        }

    }
}

